package net.apps.core.meta;

import java.util.Collection;

public interface Meta {
	
	/** getType().getType().getId() for meta-declaration */
	int ID_META_OF_META  = 0;
	/** getType().getId() for meta-declaration of protocol */
	int ID_META_OF_PROTO = 1;
	/** getType().getId() for meta-declaration of decls */
	int ID_META_OF_DECL  = 2;
	/** getType().getId() for meta-declaration of fields */
	int ID_META_OF_FIELD = 3;
	
	public enum Decl {
		/** Meta-declaration item */
		META,
		/** Protocol declaration */
		PROTOCOL,
		/** Structure/union/enum declaration */
		DECL,
		/** Single field (value, const, reference, container, etc) declaration */
		FIELD,
	}
	
	/** Declaration type - message/enum, field, enum value and so on. */ 
	Decl getDeclKind();
	
	/** Integer identifier.
	 * For meta - a number that uniquely identify the meta-declaration withing this program.
	 * For protocol - a number that uniquely identify the protocol withing this program.
	 * For types - a number that uniquely identify the message/union/enum class withing it's parent (protocol or message).
	 * For fields - a number that uniquely indentify the field withing type decl
	 * (like a field id for protobuf or field ordinal number).
	 * Note - fields and type id's overlaps! There may be field with id 0 and message with id 0!  
	 */
	int getId();
	
	/** Declaration type.
	 * For decls - struct/union/enum and so on.
	 * For fields - type of data; primitive (int, float, string, etc), collection, compaund.
	 * For containers - ordered/unordered and so on.
	 */
	Meta getType();
	
	/** Declaration type constraints.
	 * Type-specific constraints, like value or reference; signed or unsigned int;
	 * variable-length (for mostly small values) or fixed-size encoding;
	 * optional or required; ordered or unordered; and so on
	 */
	Collection<Meta> getConstraints();
	
	/** Get declaration name.
	 * For types - type name.
	 * For fields - field name.
	 * For enum values - value name.
	 */
	String getName();
	
	/** Get declaration short textual description. */
	String getDescription();
	
	/** Get enclosing meta declaration (protocol or message/enum/union) for this declaration */
	Meta getParent();

	/** Immutable collection of sub-declarations - types or fields */
	Collection<Meta> getDecls();

	/** Get meta for type declaration (message/union/enum) with specified id */
	Meta getTypeDecl(int id);

	/** Some value associated with this decl */
	Object getValue();

}
